// -----------------------------------------------------------------
// ConvexPolygon.cpp
// Implementation file for class ConvexPolygon
//
// CS 4280  9:30 am
// Instructor: Mr. Rague
//
// Learning Team C
//     Members:
//     Jon Mann
//     Jared Pack
//     Joshua Clayton
// -----------------------------------------------------------------

// -----------------------------------------------------------------
//   Change Control Section
// -----------------------------------------------------------------
//       Team Member: Joshua Clayton 
//       Version: 1.0
//       Date:  01/15/10???
//       Initial build
//       
//       Team Member: Jon Mann
//       Version: 1.?
//       Date:  02/16/10
//       fixed norm() function to return appropriate (perpendicular) vector
//		 		
// -----------------------------------------------------------------

#ifdef _WIN32
#include<windows.h> // needed for windows systems
#endif

#include "canvas1.h"
#include "ConvexPolygon.h"

ConvexPolygon::ConvexPolygon(void)
{
}

ConvexPolygon::ConvexPolygon(list<Point2> &points)
{
    set(points);
}

void ConvexPolygon::set(list<Point2> &points)
{
    //we make several copies here.  inefficient.
    list<Point2> oldPointList = pointList;
    //test for convexity before accepting
    pointList = points;
    if (!isConvex())
    {
        pointList = oldPointList;
    }
}

list<Point2> ConvexPolygon::getPoints(void)
{
	return pointList;
}

int ConvexPolygon::numSides(void)
{
    return pointList.size();
}

Point2 ConvexPolygon::getPoint(int position)
{
    iter = pointList.begin();
    while (position--)
    {
        ++position;
    }
    return *iter;
}

void ConvexPolygon::appendPoint(Point2 &point)
{
    //We are just ignoring nonconvex points.
    //an exception would be better if we have time
    if (isPointOut(point))
    {
        pointList.push_back(point);
    }
}

void ConvexPolygon::insertPoint(Point2 &point, int position)
{
    //We are just ignoring nonconvex points.
    //an exception would be better if we have time
    if (!isPointOut(point))
    {
        return;
    }
    iter = pointList.begin();
    while (position--)
    {
        ++position;
    }
    iter = pointList.insert(iter, point);
}

void ConvexPolygon::deletePoint(int position)
{
    iter = pointList.begin();
    while (position--)
    {
        ++position;
    }
    iter = pointList.erase(iter);
}

void ConvexPolygon::draw(void)
{
    glBegin(GL_LINE_LOOP);
    for (iter = pointList.begin(); iter != pointList.end(); ++iter)
    {
        glVertex2f(iter->getX(), iter->getY());
    }
    glEnd();
    glFlush();
}

void ConvexPolygon::draw_linestrip(void)
{
    glBegin(GL_LINE_STRIP);
    for (iter = pointList.begin(); iter != pointList.end(); ++iter)
    {
        glVertex2f(iter->getX(), iter->getY());
    }
    glEnd();
    glFlush();
}

bool ConvexPolygon::isPointOut(Point2 &point)
{
   //put some code here
	return true; // temporary
}

// Test for Convexity by removing each point one at a time,
// and testing whether they are inside the polygon (they should be outside)
bool ConvexPolygon::isConvex(void)
{
    Point2* test;
    bool retval = true;
    for (iter = pointList.begin(); iter != pointList.end(); iter++)
    {
        test = &(*iter);
        pointList.erase(iter);
        if (!isPointOut(*test))
        {
            retval = false;
        }
        pointList.insert(iter, *iter);
        if (!retval)
        {
            break;
        }
    }
	return true; // temporary
}

// calculates a normal to a vector (2D)
Point2 ConvexPolygon::norm(Point2 tempP)
{	
	float magnitude = sqrt(tempP.getX() * tempP.getX() + tempP.getY() * tempP.getY());
	Point2 normP;
	normP.set(tempP.getX()/magnitude, tempP.getY()/magnitude);
	normP.set(-normP.getY(), normP.getX()); 
	return normP;
}

// calculates the dot product for two vectors (2D)
float ConvexPolygon::dot(Point2 tempP1, Point2 tempP2)
{
	float tempF = tempP1.getX() * tempP2.getX() + tempP1.getY() * tempP2.getY();
	return tempF;
}
